/**
 * @description 登录、获取用户信息、退出登录、清除token逻辑，不建议修改
 */
import { useAclStore } from './acl'
import { useTabsStore } from './tabs'
import { useRoutesStore } from './routes'
import { useSettingsStore } from './settings'
import { useDictStore } from './dict'
import { UserModuleType } from '/#/store'
import { getInfo, login, loginOut } from '@/api/login/index'
import { getToken, removeToken, setToken } from '@/utils/token'
import { getTenantId, setTenantId } from '@/utils/auth'
import { resetRouter } from '@/router'
import { isArray, isString } from '@/utils/validate'
import { accessTokenKey, refreshTokenKey, tokenName } from '@/config'
import { gp } from '@gp'
import XEUtils from 'xe-utils'

export const useUserStore = defineStore('user', {
  state: (): UserModuleType => ({
    accessToken: getToken(accessTokenKey) as string,
    refreshToken: getToken(refreshTokenKey) as string,
    tenantId: getTenantId() as string,
    username: '游客',
    avatar: 'https://i.gtimg.cn/club/item/face/img/2/15922_100.gif',
    menus: [], // 菜单权限
    quserInfo: {},
  }),
  getters: {
    getAccessToken: (state) => state.accessToken,
    getRefreshToken: (state) => state.refreshToken,
    getTenantId: (state) => state.tenantId,
    getUsername: (state) => state.username,
    getAvatar: (state) => state.avatar,
    getQuserInfo: (state) => state.quserInfo,
    getMenus: (state) => state.menus,
  },
  actions: {
    /**
     * @description 设置 访问token
     * @param {*} token
     */
    setAccessToken(token: string) {
      this.accessToken = token
      setToken(token, accessTokenKey)
    } /**
     * @description 设置 刷新token
     * @param {*} token
     */,
    setRefreshToken(token: string) {
      this.refreshToken = token
      setToken(token, refreshTokenKey)
    },
    /**
     * @description 设置租户相关
     * @param {*} tenantId
     */
    setTenantId(tenantId: string) {
      this.tenantId = tenantId
      setTenantId(tenantId)
    },
    /**
     * @description 设置用户名
     * @param {*} username
     */
    setUsername(username: string) {
      this.username = username
    },
    /**
     * @description 设置头像
     * @param {*} avatar
     */
    setAvatar(avatar: string) {
      this.avatar = avatar
    },
    /**
     * @description 登录用户信息
     */
    setQuserInfo(userinfo) {
      this.quserInfo = userinfo
    },
    /**
     * @description 登录菜单
     */
    setMenus(menus) {
      this.menus = menus
    },
    /**
     * @description 登录拦截放行时，设置虚拟角色
     */
    setVirtualRoles() {
      const aclStore = useAclStore()
      aclStore.setFull(true)
      this.setUsername('admin(未开启登录拦截)')
      this.setAvatar('https://i.gtimg.cn/club/item/face/img/2/15922_100.gif')
    },
    /**
     * @description 设置token并发送提醒
     * @param {string} token 更新令牌
     * @param {string} tokenName 令牌名称
     */
    afterLogin(token: any, tokenName: string) {
      const settingsStore = useSettingsStore()
      if (token) {
        this.setAccessToken(token.accessToken)
        this.setRefreshToken(token.refreshToken)
        const hour = new Date().getHours()
        const thisTime =
          hour < 8
            ? '早上好'
            : hour <= 11
              ? '上午好'
              : hour <= 13
                ? '中午好'
                : hour < 18
                  ? '下午好'
                  : '晚上好'
        gp.$baseNotify(`欢迎登录${settingsStore.title}`, `${thisTime}！`)
      } else {
        const err = `登录接口异常，未正确返回${tokenName}...`
        gp.$baseMessage(err, 'error', 'vab-hey-message-error')
        throw err
      }
    },
    /**
     * @description 登录
     * @param {*} userInfo
     */
    async login(userInfo: any) {
      const { data } = await login(userInfo)
      //更新token
      this.afterLogin(data, tokenName)
    },
    /**
     * @description 第三方登录
     * @param {*} tokenData
     */
    async socialLogin(tokenData: any) {},
    /**
     * @description 获取用户信息接口 这个接口非常非常重要，如果没有明确底层前逻辑禁止修改此方法，错误的修改可能造成整个框架无法正常使用
     * @returns
     */
    async getUserInfo() {
      const {
        data: { menus, roles, permissions, user },
      } = await getInfo({})
      /**
       * 检验返回数据是否正常，无对应参数，将使用默认用户名,头像,Roles和Permissions
       * menus {List}
       * permissions {List}
       * roles {List}
       * user {obj}
       */
      if (
        (user && !isString(user.nickname)) ||
        (user.avatar && !isString(user.avatar)) ||
        (roles && !isArray(roles))
      ) {
        const err = '接口异常，请检查返回JSON格式是否正确'
        gp.$baseMessage(err, 'error', 'vab-hey-message-error')
        throw err
      } else {
        const aclStore = useAclStore()
        const dictStore = useDictStore()
        dictStore.getAllDictTypes()
        // 如不使用username用户名,可删除以下代码
        if (user) this.setUsername(user.nickname)
        // 如不使用avatar头像,可删除以下代码
        if (user) this.setAvatar(user.avatar)
        // 如不使用roles权限控制,可删除以下代码
        if (roles) aclStore.setRole(roles)
        // 如不使用menus头像,可删除以下代码
        if (menus) {
          //转化routes
          const menusList = []
          menus.forEach((item) => {
            const _menus = {
              path: item.path, //必须全部小写，一级路由的 path 需要带斜线
              name: item.componentName, //首字母必须大写
              component: '',
              meta: {
                type: item.type,
                title: item.name, //菜单、面包屑、多标签页显示的名称
                icon: item.icon, //图标
                url: item.component,
                target: '_blank', //是否浏览新标签页打开
                breadcrumbHidden: true, //面包屑是否显示
                dynamicNewTab: true, ////动态传参路由是否新开标签页（默认值：false
                noKeepAlive: item.keepAlive, //当前路由是否不缓存
                resources: item.permission, //权限
                hidden: item.visible, //是否显示在菜单中显示隐藏路由
                noColumn: item.noColumn, //是否隐藏分栏，仅在分栏布局中二级路由生效
                noClosable: item.noClosable, //当前路由是否可关闭多标签页
              },
              parentId: item.parentId,
              id: item.id,
              children: [],
            }
            if (item.type === 1) {
              _menus.component = 'Layout'
              if (item.openWith === 'iframe') {
                _menus.component = '@/views/other/iframe/view'
                _menus.meta.target = ''
              }
            } else if (item.type === 2) {
              if (item.openWith === 'link') {
                _menus.component = ''
                _menus.meta.target = ''
              } else if (item.openWith === 'iframe') {
                _menus.component = '@/views/other/iframe/view'
                _menus.meta.target = ''
              }
              if (item.openWith === 'locality') {
                _menus.component = `@/views/${item.component}`
                _menus.meta.target = ''
              }
            }
            menusList.push(_menus)
          })
          const _menus = XEUtils.toArrayTree(menusList, {
            parentKey: 'parentId',
            key: 'id',
            children: 'children',
          })
          //console.log(_menus)
          this.setMenus(_menus)
        }
        // 如不使用roles权限控制,可删除以下代码
        if (roles) aclStore.setRole(roles)
        // 如不使用permissions权限控制,可删除以下代码
        if (permissions) {
          aclStore.setPermission(permissions)
          aclStore.setFull(false)
        }
      }
    },
    /**
     * @description 退出登录
     */
    async logout() {
      await loginOut({})
      await this.resetAll()
      // 解决横向布局退出登录显示不全的bug
      location.reload()
    },
    /**
     * @description 重置token、roles、permission、router、tabsBar等
     */
    async resetAll() {
      this.setAccessToken('')
      this.setRefreshToken('')
      this.setQuserInfo({})
      this.setUsername('游客')
      this.setAvatar('')
      const aclStore = useAclStore()
      const routesStore = useRoutesStore()
      const tabsStore = useTabsStore()
      aclStore.setPermission([])
      aclStore.setFull(false)
      aclStore.setRole([])
      tabsStore.delAllVisitedRoutes()
      routesStore.clearRoutes()
      await resetRouter()
      removeToken(accessTokenKey)
      removeToken(refreshTokenKey)
    },
  },
})
